package com.study.lxy.newbatis.sqlSession;

import com.study.lxy.newbatis.config.Function;
import com.study.lxy.newbatis.config.MapperBean;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MyMapperProxy implements InvocationHandler {


    private MyConfiguration myConfiguration = new MyConfiguration();
    private BaseSqlFunction baseSqlFunction = new BaseSqlFunction();

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MapperBean readMapper = myConfiguration.readMapper("UserMapper.xml");
        //是否是xml文件对应的接口
        if(!method.getDeclaringClass().getName().equals(readMapper.getInterfaceName())){
            return null;
        }
        List<Function> list = readMapper.getList();
        if(null != list || list.size() != 0){
            for (Function function : list) {
                //id是否和接口方法名一样
                if(method.getName().equals(function.getFuncName())){
                    if("select".equalsIgnoreCase(function.getSqltype())) {
                        String sql = function.getSql();
                        if(args != null && args.length > 0) {
                            sql = getSql(function, args);
                            System.out.println("sql after is : " + sql);
                        }
                        List<?> result = baseSqlFunction.select(sql,Class.forName(function.getResultType()));
                        if(method.getReturnType().isAssignableFrom(List.class)){
                            return result;
                        } else {
                            return result.size() > 0 ? result.get(0) : null;
                        }
                    } else {
                        throw new Exception("不支持的SQL方法");
                    }
                }
            }
        }
        return null;
    }

    private String getSql(Function func,Object[] args) throws Exception{
        String sqlOrig = func.getSql();
        if(args.length > 1) {
            int i = 0;
            for (Object arg : args) {
                if (!arg.getClass().isPrimitive() && !arg.getClass().isAssignableFrom(String.class)) {
                    throw new Exception("多个参数时，必须都是基本类型");
                }
                sqlOrig = sqlOrig.replaceAll("#\\{arg" + i + "\\}", "'" + arg + "'");
                i++;
            }
            return sqlOrig;
        }

        Object arg = args[0];

        if(arg.getClass().isPrimitive() || arg.getClass().isAssignableFrom(String.class)){
            return sqlOrig.replaceAll("#\\{.*?\\}","'"  + arg + "'");
        }


        String regix = "#\\{(.*?)\\}";
        Pattern pattern = Pattern.compile(regix) ;
        Matcher matcher = pattern.matcher(sqlOrig) ;
        while(matcher.find()){
            String strFull = matcher.group(0);
            String fieldName = matcher.group(1).split(",")[0].trim() ;
            System.out.println("field name : " + fieldName);
            Class c = Class.forName(func.getParameterType());
            Method[] methods = c.getMethods();
            String value = "''";
            for(Method m : methods) {
                System.out.println("method name : " + m.getName());
                if(m.getName().startsWith("get") && m.getName().substring(3).equalsIgnoreCase(fieldName)){
                    System.out.println("value : " + m.invoke(arg));
                    value = "'" + m.invoke(arg).toString() + "'";
                }
            }
            sqlOrig = sqlOrig.replace(strFull,value);
        }
        return sqlOrig;
    }

}
